package com.yonyou.brigade.order_center.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yonyou.brigade.order_center.model.report.*;
import com.yonyou.brigade.order_center.service.IReportModelService;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author xiaolij
 * @date 2019/6/1 15:02
 */
@Service
public class ReportModelServiceImpl implements IReportModelService {



    @Override
    public JSONArray queryModel() {
        //返回的models
        JSONArray models = new JSONArray();

//      国内机票折扣率分析
        AirDiscount airDiscount = new AirDiscount();
        JSONObject model = getAirDiscountModel(airDiscount);

        models.add(model);
//      日报表统计
        AirDay airDay = new AirDay();
        models.add(getAirDiscountModel(airDay));

//      提前预定天数分析
        AirAdvance airAdvance = new AirAdvance();
        models.add(getAirDiscountModel(airAdvance));

//      航空公司分析
        AirLineTicket airLineTicket = new AirLineTicket();
        JSONObject airLineTicketModel = getAirDiscountModel(airLineTicket);
        InnerAirLineTicket innerAirLineTicket = new InnerAirLineTicket();
        putRefColumns(airLineTicketModel, innerAirLineTicket);
        IntAirLineTicket intAirLineTicket = new IntAirLineTicket();
        putRefColumns(airLineTicketModel, intAirLineTicket);
        models.add(airLineTicketModel);

//      国内机票退票占比
        AirRefund airRefund = new AirRefund();
        JSONObject airRefundModel = getAirDiscountModel(airRefund);
        models.add(airRefundModel);

//      航线票量统计
        AirRoute airRoute = new AirRoute();
        models.add(getAirDiscountModel(airRoute));

//      员工机票订票排名
        AirBookRank airBookRank = new AirBookRank();
        models.add(getAirDiscountModel(airBookRank));

//      个人国内订单航司分析
        AirPersonBook airPersonBook = new AirPersonBook();
        JSONObject airPersonBookModel = getAirDiscountModel(airPersonBook);
        InnerAirLineTicket innerTicket = new InnerAirLineTicket();
        putRefColumns(airPersonBookModel,innerTicket);
        AirDiscount discount = new AirDiscount();
        putRefColumns(airPersonBookModel, discount);
        models.add(airPersonBookModel);

//      未选最低价原因分析
        UnSelectLowersReason reason = new UnSelectLowersReason();
        models.add(getAirDiscountModel(reason));

        return models;
    }

    private void putRefColumns(JSONObject airLineTicketModel, Object o){
        JSONArray airLineColumns = airLineTicketModel.getJSONArray("columns");
        airLineColumns = this.getRefColumns(airLineColumns, o);
        airLineTicketModel.put("columns", airLineColumns);
    }

    private JSONArray getMembersCol(JSONArray columns, Object o){
        //获取所有的字段属性
        JSONArray fieldsInfo = this.getFiledInfo(o);
        //childref的column
        JSONObject childColumn = new JSONObject();
        JSONObject column = new JSONObject();

        String[] info = this.getModelInfo(o, "getClassInfo");
        column.put("code", info[0]);
        column.put("label", info[1]);
        column.put("type", "entity");

        JSONArray refColumns = new JSONArray();
        childColumn.put("columns", getAllColumns(fieldsInfo, refColumns, o));
        column.put("childref", childColumn);

        columns.add(column);
        return columns;
    }

    private JSONObject getAirDiscountModel(Object o){
        //每一个model模型，当前条件只返回一个model
        JSONObject model = new JSONObject();
        //model中的columns
        JSONArray columns = new JSONArray();
        String[] info = this.getModelInfo(o, "getClassInfo");
        columns = this.getColumns(columns, o);
        model.put("code", info[0]);
        model.put("columns", columns);
        model.put("root", true);
        model.put("label", info[1]);
        model.put("pkcolumn", "pk");
        return model;
    }


    /**
     * 获取属性的名称和类型
     * @param o
     * @return
     */
    private JSONArray getFiledInfo(Object o){
        JSONArray fieldsInfo = new JSONArray();
        JSONObject fieldInfo;
        Field[] fields = o.getClass().getDeclaredFields();
        for(int i = 0; i < fields.length; i++){
            fieldInfo = new JSONObject();
            //System.out.println("类型=" + fields[i].getType());
            //System.out.println("名称=" + fields[i].getName());

            fieldInfo.put("name", fields[i].getName());
            fieldInfo.put("type", fields[i].getType());
            fieldsInfo.add(fieldInfo);
        }
        return fieldsInfo;
    }

    /**
     * 返回columns对应的信息，直接获取columns方式，无childref时
     * @param columns
     * @param o
     * @return
     */
    public JSONArray getColumns(JSONArray columns, Object o){
        JSONArray fieldsInfo = this.getFiledInfo(o);
        return getAllColumns(fieldsInfo, columns, o);
    }

    /**
     * 获取columns方法，用于childref时
     * @param columns
     * @param o
     * @return
     */
    public JSONArray getRefColumns(JSONArray columns, Object o){
        //获取所有的字段属性
        JSONArray fieldsInfo = this.getFiledInfo(o);
        //childref的column
        JSONObject childColumn = new JSONObject();
        JSONObject column = new JSONObject();

        String[] info = this.getModelInfo(o, "getClassInfo");
        column.put("code", info[0]);
        column.put("label", info[1]);
        column.put("type", "entity");

        JSONArray refColumns = new JSONArray();
        childColumn.put("columns", getAllColumns(fieldsInfo, refColumns, o));
        column.put("childref", childColumn);

        columns.add(column);
        return columns;
    }

    /**
     * 获取model对应field属性的名称
     * @param obj
     * @param method
     * @return
     */
    private String[] getModelInfo(Object obj, String method){
        Object[] o = null;
        try {
            Method setMethod = obj.getClass().getMethod(method);
            obj = setMethod.invoke(obj);
            o = (Object[])obj;
        }catch (Exception e){

        }
        return (String[])o;
    }

    /**
     * 获取colums共用方法
     * @param fieldsInfo
     * @param columns
     * @param o
     * @return
     */
    private JSONArray getAllColumns(JSONArray fieldsInfo, JSONArray columns, Object o){
        JSONObject column;
        if(fieldsInfo != null && fieldsInfo.size() != 0){
            String type[];
            for (int i = 0; i < fieldsInfo.size(); i++) {
                column = new JSONObject();
                JSONObject field = fieldsInfo.getJSONObject(i);

                column.put("code", field.getString("name"));
                column.put("label", this.getModelInfo(o, "getFieldInfo")[i]);
                type = field.getString("type").split("\\.");

                //TYPE类型，后期可补充
                if("Date".equalsIgnoreCase(type[type.length - 1])){
                    column.put("type", "datetime");
                }else if ("BigDecimal".equalsIgnoreCase(type[type.length - 1])){
                    column.put("type", "DECIMAL");
                }else {
                    column.put("type", "string");
                }
                columns.add(column);
            }
        }

        return columns;
    }

}
